<?php
require_once('exceptions/QuestionnairesException.php');
require_once('model/Models.php');


class QuestionnairesManager {
	
	public function __construct() {}
	
	/**
	 * 
	 */
	public function getInactiveQuestionnairesAsArrays($oUser) {
		try {
			$aoQuestionnaires = array();
		    foreach($oUser->questionnaires as $oQuestionnaires) {
		        $aoQuestionnaires[] = $oQuestionnaires->__toArray();
		    }
		    return $aoQuestionnaires;
		} catch(Exception $e) {
		    if($e instanceof Morph_Exception_ObjectNotFound)
		        throw new Exception("Ein Objekt wurde nicht gefunden");
			else
			    throw $e;
		}
	}
	
	/**
	 * 
	 */
	public function getInactiveQuestionnaire($oUser, $sID) {
		try {
			$aoQuestionnaires = array();
		    foreach($oUser->questionnaires as $oQuestionnaire) {
		    	if($oQuestionnaire->id() == $sID)
		        	return $aoQuestionnaires;
		    }
		    throw new Exception("Fragebogen konnte nicht gefunden werden");
		} catch(Exception $e) {
		    if($e instanceof Morph_Exception_ObjectNotFound)
		        throw new Exception("Ein Objekt wurde nicht gefunden");
			else
			    throw $e;
		}
	}
	
	/**
	 * 
	 */
	public function getInactiveQuestionnaireAsArray($oUser, $sID) {
		try {
		    foreach($oUser->questionnaires as $oQuestionnaire) {
		    	if($oQuestionnaire->id() == $sID)
		        	return $oQuestionnaire->__toArray();
		    }
		    throw new Exception("Fragebogen konnte nicht gefunden werden");
		} catch(Exception $e) {
		    if($e instanceof Morph_Exception_ObjectNotFound)
		        throw new Exception("Ein Objekt wurde nicht gefunden");
			else
			    throw $e;
		}
	}

	/**
	 * 
	 */
	public function getNewQuestionnaireAsArray($oUser) {		
		try {
			$oQuestionnaire = new Questionnaire();
			$oQuestionnaire->title = "Fragebogentitel";
			$oQuestionnaire->description = "Beschreibung";
			$oQuestionnaire = $oQuestionnaire->__toArray();
			$oQuestionnaire['questionBlocks'] = array();
			$oQuestionnaire['_id'] = "new";
			
			return $oQuestionnaire;
		} catch(Exception $e) {
			throw $e;
		}
	}
	
	/**
	 * 
	 */
	public function saveQuestionnaire($oUser, $aoParams) {
        
        // if new
        
        // 	   create survey object and generate link if new
        
        // not new
        
        //     if survey belongs to user
        
        //         get survey from db if not new
        
        //         change attributes
        
        //     doesnt belong to the user
        
        //         exception
        
        // keys
        
        // check if title is free
        
        // save
        
        return;
        
        throw new QuestionnairesException("Fragebogen konnte nicht gespeichert werden");
	}
	
	/**
	 * 
	 */
	public function saveNewQuestionnaire($oUser, $oQuestionnaireJSON) {                
		$mongo = new Mongo();
		Morph_Storage::init($mongo->selectDB('befragungssystem'));
		
		try {
			if($this->isQuestionnaireDataPlausible($oQuestionnaireJSON)) {
				if($oQuestionnaireJSON->_id == "new") { // save a new survey
					
					$oQuestionnaire = new Questionnaire();
					$oQuestionnaire = $this->setNewQuestionnaireData($oQuestionnaire, $oQuestionnaireJSON);
									
					$oUser->questionnaires[] = $oQuestionnaire;
                    $oUser->firstName = $oUser->firstName;
                    $oUser->save();
				} else { // save an existing survey
					$oQuestionnaire = $this->getInactiveQuestionnaire($oUser, $oQuestionnaireJSON->_id);
					$oQuestionnaire = $this->setQuestionnaireData($oQuestionnaire, $oQuestionnaireJSON);
					$oQuestionnaire->title = $oQuestionnaire->title;
					$oQuestionnaire->save();
				}
				return $oQuestionnaire->__toArray();
			}			
		} catch(Exception $e) {
			throw $e;
		}
	}	
	
	/**
	 * Copies a questionnaire to the collection of active questionnaires
	 * and returns this copy
	 * 
	 * @param unknown_type $sQuestionnaireID
	 */
	public function makeActiveQuestionnaire($sQuestionnaireTitle) { 
		try {        
			$oActiveQuestionnaire = new ActiveQuestionnaire();
			
			$oQuery = new Morph_Query();
			$oQuery->property('title')->equals($sQuestionnaireTitle);
				   
			$oQuestionnaire = $this->getQuestionnairesFromDB($oQuery);
				   
			$oActiveQuestionnaire->title = $oQuestionnaire[0]->title;
			$oActiveQuestionnaire->description = $oQuestionnaire[0]->description;
			$oActiveQuestionnaire->questionBlocks = $oQuestionnaire[0]->questionBlocks;
						
			$oActiveQuestionnaire->save();
			
			return $oActiveQuestionnaire;
		} catch(Exception $e) {
			throw new QuestionnairesException("Fehler: Konnte Fragebogen nicht zu aktivem Fragebogen machen");
		}
	}
	
	/**
	 * Creates and returns an empty questionnaire object
	 */
	private function getNewQuestionnaire() {
		$mongo = new Mongo();
        Morph_Storage::init($mongo->selectDB("befragungssystem"));
        
		$oQuestionnaire = new Questionnaire();
		$oQuestionnaire->title = "unbenannt";
		$oQuestionnaire->save();
		
		return $oQuestionnaire;
	}
	
	/**
	 * 
	 * Enter description here ...
	 */
	private function getQuestionnairesFromDB($oQuery) {
        $mongo = new Mongo();
        Morph_Storage::init($mongo->selectDB("befragungssystem"));
        
        try {
        	$oQuestionnaire = new Questionnaire();
        	$resultSet = $oQuestionnaire->findByQuery($oQuery);
        	
	        $aoQuestionnaires = array();        
	        foreach($resultSet as $oQuestionnaire) {
			   $aoQuestionnaires[] = $oQuestionnaire;
			}
        	
        	if(sizeof($aoQuestionnaires) > 0)
				return $aoQuestionnaires;
			else
				throw new Morph_Exception_ObjectNotFound();
        } catch(Exception $e) {
        	throw $e;
        }
	}
	
	/**
	 * 
	 * Enter description here ...
	 */
	private function getQuestionnaireFromDB($sQuestionnaireID) {
        $mongo = new Mongo();
        Morph_Storage::init($mongo->selectDB("befragungssystem"));
        
        try {			
        	$oQuestionnaire = new Questionnaire();
        	$oQuestionnaire = $oQuestionnaire->loadByID($sQuestionnaireID);
        	        	
        	return $oQuestionnaire;
        } catch(Exception $e) {
        	throw $e;
        }
	}
	
	/**
	 * Checks if all questionnaire data is set and if it is plausible
	 * 
	 * @param unknown_type $asParams
	 */
	private function isQuestionnaireDataPlausible($oQuestionnaireJSON) {		
		return true; // no errors
		throw new SurveysException("Geben Sie einen Titel ein");
		throw new SurveysException("Erstellen Sie mindestens einen Fragenblock");
	}
	
	/**
	 * Sets the data of a new questionnaire
	 * 
	 * Mapping method: This method evaluates all request parameters relevant to questionnaire data 
	 * 
	 * @param unknown_type $asParams
	 */
	private function setNewQuestionnaireData($oQuestionnaire, $oQuestionnaireJSON) {
		try {
			if($this->isTitleAvailable($oQuestionnaire, $oQuestionnaireJSON->title))
				$oQuestionnaire->title = $oQuestionnaireJSON->title;
			$oQuestionnaire->description = $oQuestionnaireJSON->description;
			
			// set questionblocks
			foreach($oQuestionnaireJSON->questionBlocks as $oQuestionBlockJSON) {
			
				$iQuestionIndex = 0;
				// set questions
				foreach($oQuestionBlockJSON->questions as $oQuestionJSON) {
					if($oQuestionJSON->questionType == "singleChoiceQuestion") {
						$oQuestion = $this->mapSCQFromJS($oQuestionJSON, $iQuestionIndex);
						$oQuestionBlockJSON->singleChoiceQuestions[] = $oQuestion;
					} else if($oQuestionJSON->questionType == "singleChoiceMatrixQuestion") {
						$oQuestion = $this->mapSCMQFromJS($oQuestionJSON, $iQuestionIndex);
						$oQuestionBlockJSON->singleChoiceMatrixQuestions[] = $oQuestion;
					} else if($oQuestionJSON->questionType == "textQuestion") {
						$oQuestion = new TextQuestion();
						$oQuestion->title = $oQuestionJSON->title;
						$oQuestion->questionIndex = $iQuestionIndex;
						$oQuestionBlockJSON->textQuestions[] = $oQuestion;
					}
					$iQuestionIndex++;
				}
				$oQuestionnaire->questionBlocks[] = $oQuestionBlockJSON;
			}		
			
			return $oQuestionnaire;
		} catch(Exception $e) {
			throw $e;
		}
	}
	
	/**
	 * Maps a single choice question from JSON to Morph_Object
	 */
	private function mapSCQFromJS($oSingleChoiceQuestionJS, $iQuestionIndex) {
		$oSingleChoiceQuestion = new SingleChoiceQuestion();
		$oSingleChoiceQuestion->title = $oQuestion->title;
		foreach($oSingleChoiceQuestionJS->answers as $oSelectableAnswerJS) {
			$oSelectableAnswer = new SelectableAnswer();
			$oSelectableAnswer->title = $oSelectableAnswerJS->title;
			$oSelectableAnswer->selections = 0;
			$oSelectableAnswer->selected = true;
			$oSingleChoiceQuestion->answers[] = $oSelectableAnswer;
			$oSelectableAnswer->questionIndex = $iQuestionIndex;
		}
		return $oSingleChoiceQuestion;
	}
	
	/**
	 * Maps a single choice question from JSON to Morph_Object
	 */
	private function mapSCMQFromJS($oSingleChoiceMatrixQuestionJS, $iQuestionIndex) {
		$oQuestion = new SingleChoiceMatrixQuestion();
		foreach($oSingleChoiceMatrixQuestionJS->titles as $oSingleChoiceMatrixQuestionTitle) {
			$oSingleChoiceQuesiton = new SingleChoiceQuestion();
			$oSingleChoiceQuesiton->title = $oSingleChoiceMatrixQuestionTitle->title;
			foreach($oSingleChoiceMatrixQuestionJS->answers as $oSelectableAnswersJSON) {
				$oSelectableAnswer = new SelectableAnswer();
				$oSelectableAnswer->title = $oSelectableAnswerJSON->title;
				$oSelectableAnswer->selections = 0;
				$oSelectableAnswer->selected = true;
				$oSingleChoiceQuesiton->selectableAnswers[] = $oSelectableAnswer;
				$oSelectableAnswer->questionIndex = $iQuestionIndex;
			}
			$oQuestion->singleChoiceQuestions[] = $oSingleChoiceQuesiton;
		}
		
		return $oQuestion;
	}
	
	/**
	 * Check if a title is taken by a questionnaire with an ID different
	 * 
	 * @param unknown_type $sSurveyID
	 * @param unknown_type $sUsername
	 * 
	 * @return true title is not taken by another questionnaire
	 *         false title is taken by another questionnaire
	 */
	private function isTitleAvailable($oQuestionnaire, $sTitle) {
		$oQuery = new Morph_Query();
		$oQuery->property('title')->equals($sTitle)
			   ->property('_id')->notEqualTo($oQuestionnaire->id());
		
		try {
			$this->getQuestionnairesFromDB($oQuery, false);
			throw new QuestionnairesException("Dieser Fragebogentitel ist bereits vergeben");
		} catch(Morph_Exception_ObjectNotFound $e) {
			return true;
		} catch(QuestionnairesException $e) {
			throw $e;
		}
	}
}
?>
